package com.think.oauth.user.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.tomcat.websocket.AuthenticationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.think.common.model.CustomUser;
import com.think.common.utils.Common;
import com.think.common.utils.JSonUtil;
import com.think.common.utils.NetUtils;
import com.think.oauth.user.dao.user.UserDao;
import com.think.oauth.user.dao.user.UserOauthDao;
import com.think.oauth.user.model.Permission;
import com.think.oauth.user.model.Role;
import com.think.oauth.user.model.UserOauth;
import com.think.oauth.user.model.UserRole;
import com.think.oauth.user.qh.cas.LoginUser;

@Service
public class CustomUserDetailsService implements UserDetailsService {

	@Autowired
	private UserService userService;

	@Autowired
	private PermissionService permissionService;
	
	@Autowired
	private RoleService roleService;
	@Autowired
	private UserOauthDao oauthDao;
	
	@Autowired
	private UserRoleService userRoleService;
	private final String APP_ID = "wx4abfda6ae0d61538";
	private final String APP_SECRET = "5a5cd2014da75981943fcb7d9aae4923";

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		
		UserOauth oauth;
		if (Common.IsEmailAddress(username)) {
			oauth = oauthDao.selectUserOauthWithIDAndType(username, Common.USER_EMAIL_LOGIN);
		}
		else {
			oauth = oauthDao.selectUserOauthWithIDAndType(username, Common.USER_USERNAME_LOGIN);
		}
		
		if (oauth == null) {
			throw new UsernameNotFoundException("用户名没有找到");
		}
		if (userService.getValidUser(oauth.getUserId()) == null) {
			throw new UsernameNotFoundException("用户不存在或已经被禁用");
		}
		return new CustomUser(oauth.getIdentifier() + "", oauth.getCredential(),
				getUserPermissions(oauth.getUserId()),Common.USER_USERNAME_LOGIN,oauth.getUserId());
	}

	private Collection<GrantedAuthority> getUserPermissions(Integer userId) {
		Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
		List<String> permissions =  permissionService.getBaseMapper().selectPermissionByUserId(userId,Common.GetClient());
		if (permissions.size() == 0) {
			List<Role> roles = roleService.list(new QueryWrapper<Role>().eq("is_default", 1).eq("client", Common.GetClient()));
			Collection<UserRole> userRoles = new ArrayList<UserRole>();
			for (Role role : roles) {
				UserRole userrole = new UserRole();
				userrole.setUserId(userId);
				userrole.setRoleId(role.getRoleId());
				userrole.setCreator(userId);
				userrole.setUpdator(userId);
				userRoles.add(userrole);
			}
			if (userRoles.size()>0) {
				if (userRoleService.saveBatch(userRoles)) {
					return getUserPermissions(userId);
				}
			} 
		}
		for (String permission : permissions) {
			grantedAuthorities.add(new SimpleGrantedAuthority(permission));
		}
		return grantedAuthorities;
	}
	
	public UserDetails loadUserByWxCode(String code) throws UsernameNotFoundException {

		String passwd = "";
		UserOauth oauth = null;
		String urlString = String.format(
				"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
				APP_ID, APP_SECRET, code);
		String result = NetUtils.doGet(urlString);
		Map<String, Object> jsonMap = JSonUtil.getJsonObj(result);
		System.out.print(result);
		if (jsonMap.get("errcode") != null) {
			String errmsg = "无效的code";
			switch ((Integer) jsonMap.get("errcode")) {
			case 10003:
				errmsg = "redirect_uri域名与后台配置不一致";
				break;
			case 10004:
				errmsg = "此公众号被封禁";
				break;
			case 10005:
				errmsg = "此公众号并没有这些scope的权限";
				break;
			case 10006:
				errmsg = "必须关注此测试号";
				break;
			case 10009:
				errmsg = "操作太频繁了，请稍后重试";
				break;
			case 10010:
				errmsg = "scope不能为空";
				break;
			case 10011:
				errmsg = "redirect_uri不能为空";
				break;
			case 10012:
				errmsg = "appid不能为空";
				break;
			case 10013:
				errmsg = "state不能为空";
				break;
			case 10015:
				errmsg = "公众号未授权第三方平台，请检查授权状态";
				break;
			case 10016:
				errmsg = "不支持微信开放平台的Appid，请使用公众号Appid";
				break;
			default:
				break;
			}
			throw new UsernameNotFoundException(errmsg);
		} else {
			String openId = jsonMap.get("openid").toString();
			oauth = oauthDao.selectUserOauthWithIDAndType(openId, Common.USER_WX_LOGIN);
			com.think.oauth.user.model.User user = new com.think.oauth.user.model.User();
			if (oauth == null) {
				String accessToken = jsonMap.get("access_token").toString();
				urlString = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN",
						accessToken, openId);
				result = NetUtils.doGet(urlString);
				jsonMap = JSonUtil.getJsonObj(result);
				String nickname = jsonMap.get("nickname").toString();
				Integer gender = (Integer) jsonMap.get("sex");
				String province = jsonMap.get("province").toString();
				String city = jsonMap.get("city").toString();
				String country = jsonMap.get("country").toString();
				String headimgurl = jsonMap.get("headimgurl").toString();
				user.setAvatarUrl(headimgurl);
				user.setCountry(country);
				user.setGender(gender);
				user.setProvince(province);
				user.setNickname(nickname);
				user.setCity(city);
				oauth = new UserOauth();
				oauth.setIdentifier(openId);
				oauth.setLoginType(2);
				userService.insertUser(user, oauth);
			}

		}
		if (userService.getValidUser(oauth.getUserId()) == null) {
			throw new UsernameNotFoundException("用户不存在或已经被禁用");
		}
		return new CustomUser(oauth.getIdentifier() + "", passwd,
				getUserPermissions(oauth.getUserId()),Common.USER_WX_LOGIN,oauth.getUserId());
	}

	public UserDetails loadUserByPhoneAndSmsCode(String phone, String code) throws UsernameNotFoundException {
		String passwd = "";
		return new User(code, passwd, AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
	}
	
	public UserDetails loadUserByIlabUsername(String username,String name,String token) {
		QueryWrapper<UserOauth> wrapper = new QueryWrapper<>();
		wrapper.eq("identifier", username).eq("login_type", Common.USER_ILAB_LOGIN);
		UserOauth oauth = oauthDao.selectOne(wrapper);
		if (oauth == null) {
			oauth = new UserOauth();
			oauth.setLoginType(4);
			oauth.setIdentifier(username);
			com.think.oauth.user.model.User user =  new com.think.oauth.user.model.User();
			user.setName(name);
			user.setNickname(name);
			userService.insertUser(user, oauth);
		}
		else {
			
		}
		if (userService.getValidUser(oauth.getUserId()) == null) {
			throw new UsernameNotFoundException("用户不存在或已经被禁用");
		}
		
		return new CustomUser(oauth.getIdentifier() + "","",
				getUserPermissions(oauth.getUserId()),Common.USER_ILAB_LOGIN,oauth.getUserId(),token);
	}
	
	
	public UserDetails loadUserByQHCasUser(LoginUser casUser) {
		QueryWrapper<UserOauth> wrapper = new QueryWrapper<>();
		wrapper.eq("identifier", casUser.getAccount()).eq("login_type", Common.USER_QH_CAS_LOGIN);
		UserOauth oauth = oauthDao.selectOne(wrapper);
		if (oauth == null) {
			oauth = new UserOauth();
			oauth.setLoginType(Common.USER_QH_CAS_LOGIN);
			oauth.setIdentifier(casUser.getSsoAccount());
			com.think.oauth.user.model.User user =  new com.think.oauth.user.model.User();
			user.setName(user.getName());
			user.setNickname(user.getNickname());
			userService.insertUser(user, oauth);
		}
		else {
			
		}
		if (userService.getValidUser(oauth.getUserId()) == null) {
			throw new UsernameNotFoundException("用户不存在或已经被禁用");
		}
		
		return new CustomUser(oauth.getIdentifier() + "","",
				getUserPermissions(oauth.getUserId()),Common.USER_QH_CAS_LOGIN,oauth.getUserId(),"");
	}

}
